 #ifndef UmlRelationalItem_H
#define UmlRelationalItem_H

#include <QList>
#include <QGraphicsScene>
#include <QGraphicsItemGroup>
#include <QAction>
#include <QDebug>

#include "uml/umlgraphicsitem.h"
#include "uml/relations/buttons/inheritancebutton.h"
#include "uml/relations/buttons/implementationbutton.h"
#include "uml/siblinglist.h"
#include "uml/relations/umlrelation.h"
#include "uml/relations/ports/relationport.h"
#include "uml/relations/ports/relationportlist.h"

#define BUTTON_SPACING 10;

class SiblingList;
class ItemDragEffect;

typedef QMap<UmlRelation*, RelationPort*> PortList;
typedef QMapIterator<UmlRelation*, RelationPort*> PortListIterator;
typedef QMap<UmlRelation::RelativeItemPosition, PortList> DirectedPortList;
typedef QMapIterator<UmlRelation::RelativeItemPosition, PortList> DirectedPortListIterator;

class UmlRelationalItem : public UmlGraphicsItem {
    Q_OBJECT
public:
    UmlRelationalItem(UmlProject *project = 0);
    ~UmlRelationalItem();

    void appendButton(RelationButton *button);
    void removeButton(RelationButton *button);

    virtual void appendRelation(UmlRelation *relation, UmlRelation::RelativeItemPosition direction);
    virtual void removeRelation(UmlRelation *relation, UmlRelation::RelativeItemPosition direction);

    void removeAllRelations();

    virtual UmlRelation::RelativeItemPosition storedRelationDirection(UmlRelation *relation);
    virtual RelationPort* portForRelation(UmlRelation *relation, UmlRelation::RelativeItemPosition direction);
    void moveRelation(UmlRelation *relation, UmlRelation::RelativeItemPosition from, UmlRelation::RelativeItemPosition to);

    QList<UmlRelation*> relations();
    QList<UmlRelation*> relations(UmlRelation::RelationTypes itemType);

    QPointF centerPos();

    qreal topScene();
    qreal leftScene();
    qreal bottomScene();
    qreal rightScene();

    qreal top();
    qreal left();
    qreal bottom();
    qreal right();

    UmlRelation::RelativeItemPosition positionRelativeTo(UmlRelationalItem *item);

    virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
    virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
    virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);

    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

    void showDropEffect(bool accept);

    virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);

    UmlRelationalItem* boundingItem();

    virtual bool checkRelation(UmlRelation *possibleRelation, UmlRelationalItem *possibleRelationPartner) = 0;



protected:
    QList<RelationButton*> _buttons;

    void addButtonsToGroup();

    DirectedPortList _portList;

    QMutex _mutex;

    QMutex _portMutex;

    void updateButtonPos();  

    void showButtons();
    void hideButtons();

    bool _acceptDrop;
    bool _isSelected;

    RelationButton *_buttonUnderMouse;
    bool _buttonPressed;

    RelationButton* findButtonUnderMouse(QPointF pos);

protected slots:
    void drawPorts(UmlRelation::RelativeItemPosition);

signals:
    void itemPositionHasChanged();
};

#endif // UmlRelationalItem_H
